﻿Imports FairShop
Imports FairShop.Objects
Imports Microsoft.VisualStudio.TestTools.UnitTesting
Imports System
Imports System.Collections.Generic
Imports System.IO
Imports System.Text
Imports System.Xml
Imports System.Xml.Linq
Imports System.Xml.Schema

<TestClass()> _
Public Class TestVerkoop

    Private testContextInstance As TestContext

    '''<summary>
    '''Gets or sets the test context which provides
    '''information about and functionality for the current test run.
    '''</summary>
    Public Property TestContext() As TestContext
        Get
            Return testContextInstance
        End Get
        Set(ByVal value As TestContext)
            testContextInstance = value
        End Set
    End Property

#Region "Additional test attributes"
    '
    ' You can use the following additional attributes as you write your tests:
    '
    ' Use ClassInitialize to run code before running the first test in the class
    <ClassInitialize()> _
    Public Shared Sub MyClassInitialize(ByVal testContext As TestContext)
        AppDomain.CurrentDomain.SetData("APPBASE", Environment.CurrentDirectory)
    End Sub
    '
    ' Use ClassCleanup to run code after all tests in a class have run
    ' <ClassCleanup()> Public Shared Sub MyClassCleanup()
    ' End Sub
    '
    ' Use TestInitialize to run code before running each test
    ' <TestInitialize()> Public Sub MyTestInitialize()
    ' End Sub
    '
    ' Use TestCleanup to run code after each test has run
    <TestCleanup()> _
    Public Sub MyTestCleanup()
        Utility.ResetData()  ' zodat eventuele overgebleven wijzigingen niet doorgaat naar andere tests
    End Sub

#End Region

    Const TEST_PRIJS As Decimal = 10D
    Const TEST_STATIEGELD As Decimal = 1D
    Const TEST_AANTAL As Integer = 2

    <TestMethod()> _
    Public Sub ToevoegenMetVerkoopsdetailsTotalenTest()
        Dim verkoopRow As ArtikelsDataSet.VerkopenRow = CreateTestVerkoop()

        Dim artikelRow1 As ArtikelsDataSet.ArtikelsRow = CreateTestArtikelLeeggoed()
        Dim verkoopsDetails1 As New VerkoopsDetail(verkoopRow, artikelRow1, artikelRow1.Prijs, "", TEST_AANTAL, 1)
        Utility.Data.VerkoopsDetails.AddVerkoopsDetailsRow(verkoopsDetails1.DataRow)

        Dim artikelRow2 As ArtikelsDataSet.ArtikelsRow = CreateTestArtikelCheque()
        Dim verkoopsDetails2 As New VerkoopsDetail(verkoopRow, artikelRow2, artikelRow2.Prijs, "", TEST_AANTAL, 1)
        Utility.Data.VerkoopsDetails.AddVerkoopsDetailsRow(verkoopsDetails2.DataRow)

        Dim artikelRow3 As ArtikelsDataSet.ArtikelsRow = CreateTestArtikelBtw0()
        Dim verkoopsDetails3 As New VerkoopsDetail(verkoopRow, artikelRow3, artikelRow3.Prijs, "", TEST_AANTAL, 1)
        Utility.Data.VerkoopsDetails.AddVerkoopsDetailsRow(verkoopsDetails3.DataRow)

        Dim artikelRow4 As ArtikelsDataSet.ArtikelsRow = CreateTestArtikelBtw6()
        Dim verkoopsDetails4 As New VerkoopsDetail(verkoopRow, artikelRow4, artikelRow4.Prijs, "", TEST_AANTAL, 1)
        Utility.Data.VerkoopsDetails.AddVerkoopsDetailsRow(verkoopsDetails4.DataRow)

        Dim artikelRow5 As ArtikelsDataSet.ArtikelsRow = CreateTestArtikelBtw21()
        Dim verkoopsDetails5 As New VerkoopsDetail(verkoopRow, artikelRow5, artikelRow5.Prijs, "", TEST_AANTAL, 1)
        Utility.Data.VerkoopsDetails.AddVerkoopsDetailsRow(verkoopsDetails5.DataRow)

        Dim artikelRow6 As ArtikelsDataSet.ArtikelsRow = CreateTestArtikelBtw6MetLeeggoed()
        Dim verkoopsDetails6 As New VerkoopsDetail(verkoopRow, artikelRow6, artikelRow6.Prijs, "", TEST_AANTAL, 1)
        Utility.Data.VerkoopsDetails.AddVerkoopsDetailsRow(verkoopsDetails6.DataRow)

        Dim verkoop As New Verkoop(verkoopRow)
        Assert.AreEqual(TEST_AANTAL * (5 * TEST_PRIJS + 2 * TEST_STATIEGELD), verkoop.TotaalMetLeeggoedEnCheques)
        AssertAreNearlyEqual(TEST_AANTAL * (2 * TEST_PRIJS + 2 * TEST_STATIEGELD + 2 * TEST_PRIJS / 1.06D + 1 * TEST_PRIJS / 1.21D), verkoop.TotaalPrijsExclusief)
        AssertAreNearlyEqual(TEST_AANTAL * (2 * TEST_PRIJS / 1.06D * 0.06D + 1 * TEST_PRIJS / 1.21D * 0.21D), verkoop.TotaalBTW)
        Assert.AreEqual(TEST_AANTAL * (1 * TEST_PRIJS + 2 * TEST_STATIEGELD), verkoop.LeeggoedEnCheques)
        Assert.AreEqual(TEST_AANTAL * (2 * TEST_PRIJS + 2 * TEST_STATIEGELD), verkoop.BtwTotalen(0S).TotaalMetBtw)
        Assert.AreEqual(TEST_AANTAL * (2 * TEST_PRIJS), verkoop.BtwTotalen(6S).TotaalMetBtw)
        Assert.AreEqual(TEST_AANTAL * (1 * TEST_PRIJS), verkoop.BtwTotalen(21S).TotaalMetBtw)
        Assert.AreEqual(TEST_AANTAL * (5 * TEST_PRIJS + 2 * TEST_STATIEGELD), verkoop.Kasverschil)
        Assert.AreEqual(verkoop.TotaalZonderLeeggoedEnCheques + verkoop.LeeggoedEnCheques, verkoop.TotaalMetLeeggoedEnCheques)
    End Sub

    <TestMethod()> _
    Public Sub ToevoegenZonderVerkoopsdetailsTotalenTest()
        ' hier voegen we de details toe op normale manier, zoals bij het ophalen uit de databank
        Dim ds As ArtikelsDataSet = Dal.PrepareArtikelsDataset()
        Dim verkoopRow As ArtikelsDataSet.VerkopenRow = CreateTestVerkoop()

        Dim artikelRow1 As ArtikelsDataSet.ArtikelsRow = CreateTestArtikelLeeggoed()
        CreateVerkoopsdetail(verkoopRow, artikelRow1)

        Dim artikelRow2 As ArtikelsDataSet.ArtikelsRow = CreateTestArtikelCheque()
        CreateVerkoopsdetail(verkoopRow, artikelRow2)

        Dim artikelRow3 As ArtikelsDataSet.ArtikelsRow = CreateTestArtikelBtw0()
        CreateVerkoopsdetail(verkoopRow, artikelRow3)

        Dim artikelRow4 As ArtikelsDataSet.ArtikelsRow = CreateTestArtikelBtw6()
        CreateVerkoopsdetail(verkoopRow, artikelRow4)

        Dim artikelRow5 As ArtikelsDataSet.ArtikelsRow = CreateTestArtikelBtw21()
        CreateVerkoopsdetail(verkoopRow, artikelRow5)

        Dim artikelRow6 As ArtikelsDataSet.ArtikelsRow = CreateTestArtikelBtw6MetLeeggoed()
        CreateVerkoopsdetail(verkoopRow, artikelRow6)

        Dim verkoop As New Verkoop(verkoopRow)
        Assert.AreEqual(TEST_AANTAL * (5 * TEST_PRIJS + 2 * TEST_STATIEGELD), verkoop.TotaalMetLeeggoedEnCheques)
        AssertAreNearlyEqual(TEST_AANTAL * (2 * TEST_PRIJS + 2 * TEST_STATIEGELD + 2 * TEST_PRIJS / 1.06D + 1 * TEST_PRIJS / 1.21D), verkoop.TotaalPrijsExclusief)
        AssertAreNearlyEqual(TEST_AANTAL * (2 * TEST_PRIJS / 1.06D * 0.06D + 1 * TEST_PRIJS / 1.21D * 0.21D), verkoop.TotaalBTW)
        Assert.AreEqual(TEST_AANTAL * (1 * TEST_PRIJS + 2 * TEST_STATIEGELD), verkoop.LeeggoedEnCheques)
        Assert.AreEqual(TEST_AANTAL * (2 * TEST_PRIJS + 2 * TEST_STATIEGELD), verkoop.BtwTotalen(0S).TotaalMetBtw)
        Assert.AreEqual(TEST_AANTAL * (2 * TEST_PRIJS), verkoop.BtwTotalen(6S).TotaalMetBtw)
        Assert.AreEqual(TEST_AANTAL * (1 * TEST_PRIJS), verkoop.BtwTotalen(21S).TotaalMetBtw)
        Assert.AreEqual(TEST_AANTAL * (5 * TEST_PRIJS + 2 * TEST_STATIEGELD), verkoop.Kasverschil)
        Assert.AreEqual(verkoop.TotaalZonderLeeggoedEnCheques + verkoop.LeeggoedEnCheques, verkoop.TotaalMetLeeggoedEnCheques)
    End Sub

#Region "Helperfuncties"

    Private Function CreateTestVerkoop() As ArtikelsDataSet.VerkopenRow
        Dim ds As ArtikelsDataSet = Utility.Data
        Dim verkoopRow As ArtikelsDataSet.VerkopenRow = ds.Verkopen.NewVerkopenRow()
        verkoopRow.KlantenRow = ds.Klanten(0)
        verkoopRow.CashBetaald = True
        verkoopRow.WinkeliersRow = ds.Winkeliers(0)
        verkoopRow.VerkoopsoortenRow = ds.Verkoopsoorten(0)
        verkoopRow.Datum = DateTime.Today()
        verkoopRow.Tijd = "Niet van toepassing"
        verkoopRow.Begintotaal = 0D
        verkoopRow.Eindtotaal = 0D
        verkoopRow.CommentaarBegintotaal = ""
        verkoopRow.CommentaarEindtotaal = ""
        verkoopRow.InUitKasBedrag = 0D
        verkoopRow.InUitKasReden = ""
        verkoopRow.NaarBankBedrag = 0D
        verkoopRow.NaarBankNaam = ""
        verkoopRow.NaarBankReferentie = 0
        verkoopRow.FactuurNummer = 0
        verkoopRow.IsFactuurBehandeld = False
        verkoopRow.Omschrijving = ""
        verkoopRow.BedragBancontact = 0D
        verkoopRow.BedragMaaltijdcheques = 0D
        ds.Verkopen.AddVerkopenRow(verkoopRow)
        Dal.VerkoopToevoegen(verkoopRow)
        Return verkoopRow
    End Function

    Private Sub CreateVerkoopsdetail(ByVal verkoop As ArtikelsDataSet.VerkopenRow, _
            ByVal artikel As ArtikelsDataSet.ArtikelsRow)
        Dim ds As ArtikelsDataSet = Utility.Data
        Dim verkoopsdetail As ArtikelsDataSet.VerkoopsDetailsRow = ds.VerkoopsDetails.NewVerkoopsDetailsRow()
        verkoopsdetail.VerkopenRow = verkoop
        verkoopsdetail.ArtikelsRow = artikel
        verkoopsdetail.Aantal = TEST_AANTAL
        verkoopsdetail.Omschrijving = artikel.Omschrijving
        verkoopsdetail.ExtraOmschrijving = ""
        verkoopsdetail.Barcode = artikel.Barcode
        verkoopsdetail.BTW = artikel.BTW
        verkoopsdetail.Status = StatusImage.Huidig
        verkoopsdetail.VolgnummerKlant = 1
        If (artikel.IsLeeggoed) Then
            ' dit wordt normaal gedaan vooraleer het in de databank terecht komt, dus doen we het hier manueel
            verkoopsdetail.Prijs = 0D
            verkoopsdetail.StatiegeldEuro = artikel.Prijs
        Else
            verkoopsdetail.Prijs = artikel.Prijs
            verkoopsdetail.StatiegeldEuro = artikel.StatiegeldEuro
        End If
        ds.VerkoopsDetails.AddVerkoopsDetailsRow(verkoopsdetail)
    End Sub

    Private Function CreateArtikelBase() As ArtikelsDataSet.ArtikelsRow
        Dim ds As ArtikelsDataSet = Utility.Data
        Dim artikelsRow As ArtikelsDataSet.ArtikelsRow = ds.Artikels.NewArtikelsRow()
        artikelsRow.Omschrijving = "Testomschrijving"
        artikelsRow.Barcode = "Testbarcode"
        artikelsRow.StatiegeldEuro = 0D
        'artikelsRow.DatumToegevoegd = DateTime.Now()
        ds.Artikels.AddArtikelsRow(artikelsRow)
        Return artikelsRow
    End Function

    Private Function CreateTestArtikelCheque() As ArtikelsDataSet.ArtikelsRow
        Dim artikelsRow As ArtikelsDataSet.ArtikelsRow = CreateArtikelBase()
        artikelsRow.Artikelcode = "TESTC"
        artikelsRow.Prijs = TEST_PRIJS
        artikelsRow.BTW = 0D
        artikelsRow.IsCheque = True
        Return artikelsRow
    End Function

    Private Function CreateTestArtikelLeeggoed() As ArtikelsDataSet.ArtikelsRow
        Dim artikelsRow As ArtikelsDataSet.ArtikelsRow = CreateArtikelBase()
        artikelsRow.Artikelcode = "TESTL"
        artikelsRow.Prijs = TEST_STATIEGELD
        artikelsRow.BTW = 0D
        artikelsRow.IsLeeggoed = True
        Return artikelsRow
    End Function

    Private Function CreateTestArtikelBtw0() As ArtikelsDataSet.ArtikelsRow
        Dim artikelsRow As ArtikelsDataSet.ArtikelsRow = CreateArtikelBase()
        artikelsRow.Artikelcode = "TEST0"
        artikelsRow.Prijs = TEST_PRIJS
        artikelsRow.BTW = 0D
        Return artikelsRow
    End Function

    Private Function CreateTestArtikelBtw6() As ArtikelsDataSet.ArtikelsRow
        Dim artikelsRow As ArtikelsDataSet.ArtikelsRow = CreateArtikelBase()
        artikelsRow.Artikelcode = "TEST6"
        artikelsRow.Prijs = TEST_PRIJS
        artikelsRow.BTW = 6D
        Return artikelsRow
    End Function

    Private Function CreateTestArtikelBtw21() As ArtikelsDataSet.ArtikelsRow
        Dim artikelsRow As ArtikelsDataSet.ArtikelsRow = CreateArtikelBase()
        artikelsRow.Artikelcode = "TEST21"
        artikelsRow.Prijs = TEST_PRIJS
        artikelsRow.BTW = 21D
        Return artikelsRow
    End Function

    Private Function CreateTestArtikelBtw6MetLeeggoed() As ArtikelsDataSet.ArtikelsRow
        Dim artikelsRow As ArtikelsDataSet.ArtikelsRow = CreateArtikelBase()
        artikelsRow.Artikelcode = "TEST6L"
        artikelsRow.Prijs = TEST_PRIJS
        artikelsRow.BTW = 6D
        artikelsRow.StatiegeldEuro = TEST_STATIEGELD
        Return artikelsRow
    End Function

    Private Sub AssertAreNearlyEqual(ByVal value1 As Decimal, ByVal value2 As Decimal)
        Assert.AreEqual(Math.Round(value1, 3), Math.Round(value2, 3))
    End Sub

#End Region

End Class